package com.vodafone.nocs.inops.tools.fix;

import java.io.*;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.Options;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import com.vodafone.nocs.inops.tools.fix.generated.Fix199Logic;
import com.vodafone.nocs.inops.tools.fix.generated.Fix199Logic.Bundle;
import com.vodafone.nocs.inops.tools.fix.generated.Fix199Logic.Bundle.Counter;
import com.vodafone.nocs.inops.tools.fix.generated.Fix199Logic.Bundle.Rules.Case;
import com.vodafone.nocs.inops.tools.fix.generated.Fix199Logic.Bundle.Rules.Case.Action;

// todo
// queued bundles date check

// ldapsearch -b dview=XAN-IN-RDR3_request_data -h 127.0.0.1 -u -V 2 -l 1000 -w123 -p 1972 -s one 
// -D dview=XAN-IN-RDR3_request_data "sid=OP=A;ACTION=IMOM#RMV:BUNDLE,MSISDN=447826679831,PTP_ID=FP_VF_D80,IDTYPE=S,ONLY_ACTIVE=N"
//
//  ldapsearch -b dview=XAN-IN-RDR3_request_data -h 127.0.0.1 -u -V 2 -l 1000 -w123 -p 1972 -s one 
//  -D dview=XAN-IN-RDR3_request_data 
//  "sid=OP=A;ACTION=IMOM#SUB:DTPBUNDLE,MSISDN=447826679831,PTP_ID=FP_VF_D80,START_DATE=2014/01/27,END_DATE=2014/02/25,IDTYPE=S,PAYMENT_ID=EXTERNAL,BAL=P,ALLOW_SPD=N,UCL=N"

public class Fix199 {

	final private static Integer COUNTERS = 0;
	final private static Integer BUNDLES = 1;

	final private static Integer SKIP = 1;
	final private static Integer WARNING = 2;
	final private static Integer DELETE = 4;
	final private static Integer PROVISION = 8;
	final private static Integer FAULTNOFIX = 16;

	final private static Integer CTOK = 1;
	final private static Integer BUCKETSTARTDATEMISSING = 2;
	final private static Integer BUCKETENDDATEMISSING = 4;
	final private static Integer NOBUCKET = 8;
	final private static Integer NOCOUNTER = 16;
	final private static Integer BUNDLEENDDATEMISSING = 32;
	final private static Integer BUCKETISEXHAUSTED = 64;
	final private static Integer UNKNOWNISSUE = 128;

	final private static boolean test = false;

	private static int debuglogLevel = 0;
	private static int omlogLevel = 1;
	private static int outputLevel = 1;

	private static int sourceData = 1; // file, 1 is ldap
	
	private static boolean rawFile = false;
	
	private static boolean stream = false;
	
	private static boolean statsOnly = false;


	private static Fix199Logic bundlesDef = null;
	
	private static int Issues = 0;
	private static int TotMsisdn = 0;
	private static int QueuedBundle = 0;

	public static void main(String args[]) {

		try {

			// load xml
			JAXBContext catesurepay = JAXBContext
					.newInstance("com.vodafone.nocs.inops.tools.fix.generated");
			Unmarshaller bundlesDefMarsh = catesurepay.createUnmarshaller();
			bundlesDef = (Fix199Logic) bundlesDefMarsh
					.unmarshal(new FileInputStream("FIDLogic.xml"));

			String FileName = new String();

			ArrayList<String> MSISDNS = new ArrayList<String>();

			// Command line
			CommandLineParser parser = new GnuParser();

			Options options = new Options();
			options.addOption("d", "debug", false, "debug output");
			options.addOption("m", "msisdn", true, "single MSISDN");
			options.addOption("sq", "skipqueued", false, "skip queued bundles");
			options.addOption("f", "file", true, "file name");
			options.addOption("r", "raw", false, "raw");
			options.addOption("s", "stream", false, "stream");
			options.addOption("stat", "stats only", false, "stream");
			options.addOption("dump", "dump", false, "dump");



			CommandLine line = parser.parse(options, args);

			if (line.hasOption("dump")){
				sourceData = 0;
			}else{
				
			}
			if (line.hasOption("s")) {
				stream = true;
			}
			if (line.hasOption("stat")) {
				statsOnly = true;
			}
			if (line.hasOption("d")) {
				debuglogLevel = 1;
			}
			if (line.hasOption("m")) {
				MSISDNS.add(line.getOptionValue("m"));
			} else if (line.hasOption("f") ) {
				FileName = line.getOptionValue("f");
				if ( sourceData == 1){
					BufferedReader br = null;
					try {
						String sCurrentLine;
						br = new BufferedReader(new FileReader(FileName));
						while ((sCurrentLine = br.readLine()) != null) {
							MSISDNS.add(sCurrentLine);
						}

					} catch (IOException e) {
						e.printStackTrace();
					} finally {
						try {
							if (br != null)
								br.close();
						} catch (IOException ex) {
							ex.printStackTrace();
						}
					}
				}
			}
			if (line.hasOption("r")) {
				rawFile = true;
			}

			if (stream){
				
			}
			else{
				
			}
			
			// Load bundles
			// <MSISDN,BundleInfo[]>
			Map<String, ArrayList<BundleInfo>> bundles = fetchBundles(MSISDNS, FileName);

			// Load counters, due to queueing it has to be a multimap
			// ??
			// <MSISDN:CID,BundleInfo[]>
			Multimap<String, BundleInfo> counters = fetchCounters(MSISDNS, FileName);
			
			if (sourceData == 0){
				int i = 0;
				Iterator iterator = bundles.entrySet().iterator();
				while (iterator.hasNext()) {
					i++;
					Map.Entry mapEntry = (Map.Entry) iterator.next();
					String theK = new String();
					theK = (String) mapEntry.getKey();
					MSISDNS.add(theK);
					DEBLOG("add [" + theK + "]");
				}
				STATLOG("#   MSISDN " + i + " " + MSISDNS.size());
			}

			DEBLOG("###################################################################");
			DEBLOG("# BUNDLES");
			printMap(bundles);
			DEBLOG("###################################################################");

			DEBLOG("###################################################################");
			DEBLOG("# COUNTERS");
			printMMap(counters);
			DEBLOG("###################################################################");

			boolean toFix = false;
			// loop on subs
			for (String _msisdn : MSISDNS) {
				
				toFix = false;
				
				// # are skipped
				if (_msisdn.startsWith("#")) {
					OUTLOG("###################################################################\n# Skip "
							+ _msisdn + "\n");
					OUTLOG("###################################################################");
					continue;
				}
				if (_msisdn.length() == 0) {
					continue;
				}

				OUTLOG("###################################################################\n# START "
						+ _msisdn);

				// get the bundles for that given msisdn
				ArrayList<BundleInfo> _binfo = bundles.get(_msisdn);

				// this says how many bundles of the same type (used in queue)
				Map<String, Integer> _totQbun = new HashMap<String, Integer>();
				
				// this block identifies queues
				// each bundle as a property to identify is queued or not
				// and the position in the queue (start = 0)
				{
					// this is a trick to check duplicated (queued) bundles
					Map<String, BundleInfo> _cq = new HashMap<String, BundleInfo>();
					for (BundleInfo __bf : _binfo) {
						if (_cq.containsKey(__bf.getBundleId())) {
							_cq.get(__bf.getBundleId()).setQueued(true);
							__bf.setQueued(true);
							__bf.setPlaceInQueue(_cq.get(__bf.getBundleId())
									.getPlaceInQueue() + 1);
						}
						if (_totQbun.containsKey(__bf.getBundleId())) {
							int i = _totQbun.get(__bf.getBundleId());
							i++;
							_totQbun.put(__bf.getBundleId(), i);
						} else {
							_totQbun.put(__bf.getBundleId(), 1);
						}
						_cq.put(__bf.getBundleId(), __bf);
					}
					if (_cq.size() < _binfo.size()) {
						OUTLOG("# QUEUED BUNDLES FOUND.");
						printArray(_binfo);
						printMap2(_totQbun);
						if (line.hasOption("sq")) {
							OUTLOG("# SKIPPED.");
							OUTLOG("###################################################################\n\n");
							QueuedBundle++;
							TotMsisdn++;
							continue;
						}
						OUTLOG("###################################################################\n\n");
					}
				}

				// start here to check
				// for each bundle...
				for (BundleInfo _bf : _binfo) {

					// get the counter name(s) from xml
					if (_bf.getBundleId() != null
							&& ( _bf.getBundleId().length()>0 && _bf.getBundleId().startsWith("FP_")) ) {
						ArrayList<String> counterName = getCounterName(_bf
								.getBundleId());
						if (counterName == null || counterName.isEmpty()) {
							OUTLOG("Bundle " + _bf.getBundleId()
									+ " has no counter associated. Check XML.");
							continue;
						}

						// show the counters
						DEBLOG("# Bundle " + _bf.getBundleId()
								+ " counter(s): " + expandSArray(counterName));
						
						//check here if bundle has already expired
						//can happen with dumps...
						boolean expired = false;
						if (_bf.getEndDate() != null && _bf.getEndDate().length() > 0) {
							try{
								SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
								Date edate = formatter.parse(_bf.getEndDate());
								
								Calendar cal = Calendar.getInstance();
								expired = edate.before(cal.getTime());
							}
							
							catch (ParseException e) {
								OUTLOG("# Unexpected end date "+e.getMessage());

							}
							if (expired)
								OUTLOG("# End date ("+_bf.getEndDate()+") already passed, bundle ["+ _bf.getBundleId() +"] will not be reprovisioned"); 
						}

						// these are used to send a single delete and provision
						// when the counter has more than one issue
						boolean _delete = false;
						boolean _provision = false;
						boolean _noAction = false;
						
						// when more than one counter
						if (counterName != null && counterName.size() > 1) {
							DEBLOG("getCounterName is multiple "
									+ counterName.size());

							for (String _ctrn : counterName) {
								DEBLOG("counterName.get(0) " + _ctrn);

								// load all matching subscriber counters
								Collection<BundleInfo> counterColl = counters
										.get(_msisdn + ":" + _ctrn);

								// invoke check and correct logic
								int _result = fixIt(_msisdn, _bf, counterColl);
								// these are needed to delete and provision the
								// bundle one regardless
								// of how many faulty related counters it has
								_delete = ((_result & DELETE) == DELETE)
										|| _delete;
								_provision = ((_result & DELETE) == DELETE)
										|| _provision;
								_noAction = ((_result &  FAULTNOFIX) == FAULTNOFIX)
										|| _noAction;
								_noAction = ((_result &  FAULTNOFIX) == FAULTNOFIX)
										|| _noAction;

							}

						}
						// one counter for that given bundle
						else {
							String _cn = counterName.get(0);

							Collection<BundleInfo> counterColl = counters
									.get(_msisdn + ":" + _cn);

							int _result = fixIt(_msisdn, _bf, counterColl);
							_delete = ((_result & DELETE) == DELETE) || _delete;
							_provision = ((_result & DELETE) == DELETE)
									|| _provision;
							_noAction = ((_result &  FAULTNOFIX) == FAULTNOFIX)
									|| _noAction;
						}

						// print ldapcommand delete bundle
						if (_delete && !expired) {
							toFix = true;
							if (!statsOnly)
								sendDeleteMessage(_msisdn, _bf);
						}

						// when faulty queued bundle we delete all instances but
						// reprovision only one
						// the last placed instance of queued bundle triggers
						// provisioning
						if (_provision && ! expired 
								&& ((_totQbun.get(_bf.getBundleId()) - 1) == _bf
										.getPlaceInQueue())) {
							toFix = true;
							if (!statsOnly)
								sendProvisionMessage(_msisdn, _bf);
						}
					}
				}
				OUTLOG("###################################################################\n\n");
				if(toFix){
					Issues ++;
				}
				TotMsisdn++;
			}
		} catch (Exception e) {
			OMLOG("exception happened - here's what I know: ");
			e.printStackTrace();
			System.exit(-1);
		}
		STATLOG("###################################################################\n\n");
		STATLOG("####### TotMsisdn " + TotMsisdn +"\n\n");
		STATLOG("####### Queued    " + QueuedBundle +"\n\n");
		STATLOG("####### Issues    " + Issues +"\n\n");
		STATLOG("###################################################################\n\n");

		System.exit(0);
	}

	private static int fixIt(String MSISDN, BundleInfo _bf,
			Collection<BundleInfo> counterColl) {

		DEBLOG("fixIt " + MSISDN);

		int returnAction = 0;

		// identify issue here
		int theIssue = getIssue(_bf, counterColl);

		boolean provision = false;
		boolean delete = false;
		boolean skip = false; // this overrides all
		boolean faultNoAction = false;

		if ((theIssue & NOCOUNTER) == NOCOUNTER) {
			int theFix = getFix(_bf, NOCOUNTER);
			provision = ((theFix & PROVISION) == PROVISION) || provision;
			delete = ((theFix & DELETE) == DELETE) || delete;
			skip = ((theFix & SKIP) == SKIP) || skip;
			// do actions except delete and provision which are left outside
			if ((theFix & WARNING) == WARNING && !statsOnly) {
				sendWarning(MSISDN, _bf, NOCOUNTER);
			}
		}

		if ((theIssue & BUCKETSTARTDATEMISSING) == BUCKETSTARTDATEMISSING) {
			int theFix = getFix(_bf, BUCKETSTARTDATEMISSING);
			provision = ((theFix & PROVISION) == PROVISION) || provision;
			delete = ((theFix & DELETE) == DELETE) || delete;
			skip = ((theFix & SKIP) == SKIP) || skip;
			if ((theFix & WARNING) == WARNING && !statsOnly) {
				sendWarning(MSISDN, _bf, BUCKETSTARTDATEMISSING);
			}
		}
		if ((theIssue & BUCKETENDDATEMISSING) == BUCKETENDDATEMISSING) {
			int theFix = getFix(_bf, BUCKETENDDATEMISSING);
			provision = ((theFix & PROVISION) == PROVISION) || provision;
			delete = ((theFix & DELETE) == DELETE) || delete;
			skip = ((theFix & SKIP) == SKIP) || skip;
			if ((theFix & WARNING) == WARNING && !statsOnly) {
				sendWarning(MSISDN, _bf, BUCKETENDDATEMISSING);
			}
		}
		if ((theIssue & NOBUCKET) == NOBUCKET) {
			int theFix = getFix(_bf, NOBUCKET);
			provision = ((theFix & PROVISION) == PROVISION) || provision;
			delete = ((theFix & DELETE) == DELETE) || delete;
			skip = ((theFix & SKIP) == SKIP) || skip;
			if ((theFix & WARNING) == WARNING && !statsOnly) {
				sendWarning(MSISDN, _bf, NOBUCKET);
			}
		}
		if ((theIssue & BUNDLEENDDATEMISSING) == BUNDLEENDDATEMISSING) {
			int theFix = getFix(_bf, BUNDLEENDDATEMISSING);
			provision = ((theFix & PROVISION) == PROVISION) || provision;
			delete = ((theFix & DELETE) == DELETE) || delete;
			skip = ((theFix & SKIP) == SKIP) || skip;
			if ((theFix & WARNING) == WARNING && !statsOnly) {
				sendWarning(MSISDN, _bf, BUNDLEENDDATEMISSING);
			}
		}
		if ((theIssue & UNKNOWNISSUE) == UNKNOWNISSUE) {
			faultNoAction = true;
			sendWarning(MSISDN, _bf, UNKNOWNISSUE);
		}

		if (delete && !skip) {
			returnAction = DELETE;
		}
		if (provision && !skip) {

			if (((theIssue & BUCKETISEXHAUSTED) == BUCKETISEXHAUSTED)) {
				if (!statsOnly)
					OUTLOG("# Warning you are reprovisioning a bundle which is already exhausted.");
			}

			returnAction = returnAction + PROVISION;
		}
		if (faultNoAction){
			returnAction = returnAction + FAULTNOFIX;
		}
		return returnAction;
	}

	private static void sendProvisionMessage(String mSISDN, BundleInfo _bf) {
		// DEBLOG("sendProvisionMessage(String mSISDN, BundleInfo _bf) " +
		// mSISDN +" " + _bf.getBundleId());
		OUTLOG("###################################################################");
		OUTLOG("# Provision of");
		OUTLOG("# MSISDN [" + mSISDN + "]");
		OUTLOG("# Bundle [" + _bf.getBundleId() + "]");
		OUTLOG("# Bundle start [" + _bf.getStartDate() + "]");
		OUTLOG("# Bundle end   [" + _bf.getEndDate() + "]");
		
		
		//case 1 null null
		//case 2 date null
		//case 3 

		int days = 0;
		boolean startTodayCurrentEnd = false;
		boolean startNextHour = false;
		//boolean startTodayFullDuration = false;

		boolean bundleDate = false;

		//get from xml
		for (Bundle _b : bundlesDef.getBundle()) {
			if (_b.getName().compareTo(_bf.getBundleId()) == 0) {
				if (_b.getDuration().getDays() != null
						&& _b.getDuration().getDays().length() > 0) {
					days = Integer.parseInt(_b.getDuration().getDays());
				}
				if (_b.getDates() != null
						&& _b.getDates().getDates().length() > 0) {
					if (_b.getDates().getDates().compareTo("bundleDate") == 0)
						bundleDate = true;
					if (_b.getDates().getDates()
							.compareTo("startNextHour") == 0)
						startNextHour = true;
				}
			}
		}

		String StartDate = new String();
		String EndDate = new String();
		String StartTime = new String();

		//to check
		if (bundleDate) {
			OUTLOG("# Start and End same as bundle");
			SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
			SimpleDateFormat formatter2 = new SimpleDateFormat("yyyy/MM/dd");

			try {
				if (_bf.getStartDate() != null
						&& _bf.getStartDate().length() > 0) {
					Date sdate = formatter.parse(_bf.getStartDate());
					StartDate = formatter2.format(sdate);
				} else {
					DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
					Calendar cal = Calendar.getInstance();
					StartDate = dateFormat.format(cal.getTime());
				}
				if (_bf.getEndDate() != null && _bf.getEndDate().length() > 0) {
					Date edate = formatter.parse(_bf.getEndDate());
					EndDate = formatter2.format(edate);
				}
				// check if we are giving more than the allowed durat
			} catch (ParseException e) {
				OUTLOG("Exception with "+mSISDN);
				e.printStackTrace();
			}
		}
		else if (startNextHour){
			OUTLOG("# Start in future and End same as bundle");
			try {
				DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
				DateFormat hourFormat = new SimpleDateFormat("HHmm");
				Calendar cal = Calendar.getInstance();
				cal.add(Calendar.HOUR, 3);
				StartDate = dateFormat.format(cal.getTime());
				StartTime = hourFormat.format(cal.getTime());

				if (_bf.getEndDate() != null && _bf.getEndDate().length() > 0) {
					SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
					SimpleDateFormat formatter2 = new SimpleDateFormat("yyyy/MM/dd");
					Date edate = formatter.parse(_bf.getEndDate());
					EndDate = formatter2.format(edate);
				}
				
			} catch (ParseException e) {
				OUTLOG("Exception with "+mSISDN);
				e.printStackTrace();
			}

		}
//		else if (startTodayCurrentEnd && _bf.getEndDate().length() != 0) {
//			OUTLOG("# End same as bundle");
//			SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
//			SimpleDateFormat formatter2 = new SimpleDateFormat("yyyy/MM/dd");
//
//			DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
//			Calendar cal = Calendar.getInstance();
//			StartDate = dateFormat.format(cal.getTime());
//			try {
//				Date edate = formatter.parse(_bf.getEndDate());
//				EndDate = formatter2.format(edate);
//			} catch (ParseException e) {
//				e.printStackTrace();
//			}
////		}
//		else {// (startTodayFullDuration || _bf.getStartDate().length() == 0
//				// || _bf.getEndDate().length()==0){
//			OUTLOG("# Start Today and full duration of " + days);
//			DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
//			Calendar cal = Calendar.getInstance();
//			StartDate = dateFormat.format(cal.getTime());
//			cal.add(Calendar.DATE, days);
//			EndDate = dateFormat.format(cal.getTime());
//		}
		OUTLOG("# Dates [" + StartDate + "] ["+StartTime+"][" + EndDate + "]");

		// warning if end-start > days or some messes
		try {
			SimpleDateFormat formatter2 = new SimpleDateFormat("yyyy/MM/dd");
			Date sDate = formatter2.parse(StartDate);
			if (EndDate.length() > 0) {
				Date eDate = formatter2.parse(EndDate);
				if (days > 0) {
					Calendar cal = Calendar.getInstance();
					if (sDate.compareTo(cal.getTime()) > 0) {
						// start after today
						if ((eDate.getTime() - sDate.getTime())
								/ (24 * 60 * 60 * 1000) > days) {
							OUTLOG("# Warning end - start over the duration of the bundle");
						}
					} else {
						if ((eDate.getTime() - cal.getTime().getTime())
								/ (24 * 60 * 60 * 1000) > days) {
							OUTLOG("# Warning end - start over the duration of the bundle");
						}
					}
				}

			} else if (days != 0) {
				OUTLOG("# Warning no end date set for a Bundle with limited duration");
			}

		} catch (ParseException e) {
			e.printStackTrace();
		}

		String StartTimeCommand = new String("");
		if (StartTime.length() > 0){
			StartTimeCommand = ",START_TIME="+StartTime;
		}
		if (EndDate.length() > 0)
				OUTLOG("ldapsearch -b dview=XAN-IN-RDR3_request_data -h 127.0.0.1 -u -V 2 -l 1000 -w123 -p 1972 -s one -D dview=XAN-IN-RDR3_request_data \"sid=OP=A;ACTION=IMOM#SUB:DTPBUNDLE,MSISDN="
					+ mSISDN
					+ ",PTP_ID="
					+ _bf.getBundleId()
					+ ",START_DATE="
					+ StartDate
					+ StartTimeCommand
					+ ",END_DATE="
					+ EndDate
					+ ",IDTYPE=S,PAYMENT_ID=EXTERNAL,BAL=P,ALLOW_SPD=N,UCL=N\"");
		else
			OUTLOG("ldapsearch -b dview=XAN-IN-RDR3_request_data -h 127.0.0.1 -u -V 2 -l 1000 -w123 -p 1972 -s one -D dview=XAN-IN-RDR3_request_data \"sid=OP=A;ACTION=IMOM#SUB:DTPBUNDLE,MSISDN="
					+ mSISDN
					+ ",PTP_ID="
					+ _bf.getBundleId()
					+ ",START_DATE="
					+ StartDate
					+ ",IDTYPE=S,PAYMENT_ID=EXTERNAL,BAL=P,ALLOW_SPD=N,UCL=N\"");

		// ldapsearch -b dview=XAN-IN-RDR3_request_data -h 127.0.0.1 -u -V 2 -l
		// 1000 -w123 -p 1972 -s one
		// -D dview=XAN-IN-RDR3_request_data
		// "sid=OP=A;ACTION=IMOM#SUB:DTPBUNDLE,MSISDN=447826679831,PTP_ID=FP_VF_D80,START_DATE=2014/01/27,END_DATE=2014/02/25,IDTYPE=S,PAYMENT_ID=EXTERNAL,BAL=P,ALLOW_SPD=N,UCL=N"

		// ldapsearch -b dview=XAN-IN-RDR3_request_data -h 127.0.0.1 -u -V 2 -l 1000 -w123 -p 1972 -s one
		// -D dview=XAN-IN-RDR3_request_data
		// "sid=OP=A;ACTION=IMOM#SUB:DTPBUNDLE,MSISDN=447826679831,PTP_ID=FP_VF_D04,START_DATE=2014/02/25,START_TIME=1800,END_DATE=2014/02/26,IDTYPE=S,PAYMENT_ID=EXTERNAL,BAL=P,ALLOW_SPD=N,UCL=N"

		
	}

	private static void sendDeleteMessage(String mSISDN, BundleInfo _bf) {
		// DEBLOG("sendDeleteMessage(String mSISDN, BundleInfo _bf) " + mSISDN
		// +" " + _bf.getBundleId());
		OUTLOG("###################################################################");
		OUTLOG("# Deletion of");
		OUTLOG("# MSISDN [" + mSISDN + "]");
		OUTLOG("# Bundle [" + _bf.getBundleId() + "]");

		// ldapsearch -b dview=XAN-IN-RDR3_request_data -h 127.0.0.1 -u -V 2 -l
		// 1000 -w123 -p 1972 -s one
		// -D dview=XAN-IN-RDR3_request_data
		// "sid=OP=A;ACTION=IMOM#RMV:BUNDLE,MSISDN=447826679831,PTP_ID=FP_VF_D80,IDTYPE=S,ONLY_ACTIVE=N"

		OUTLOG("ldapsearch -b dview=XAN-IN-RDR3_request_data -h 127.0.0.1 -u -V 2 -l 1000 -w123 -p 1972 -s one -D dview=XAN-IN-RDR3_request_data \"sid=OP=A;ACTION=IMOM#RMV:BUNDLE,MSISDN="
				+ mSISDN
				+ ",PTP_ID="
				+ _bf.getBundleId()
				+ ",IDTYPE=S,ONLY_ACTIVE=N\"");

	}

	private static void sendWarning(String mSISDN, BundleInfo _bf, Integer type) {
		OUTLOG("###################################################################");
		OUTLOG("# Warning!");
		OUTLOG("# MSISDN [" + mSISDN + "]");
		OUTLOG("# Bundle [" + _bf.getBundleId() + "]");
		if (type == NOCOUNTER)
			OUTLOG("# Has no counter.");
		else if (type == BUCKETSTARTDATEMISSING)
			OUTLOG("# Bucket has no start date.");
		else if (type == BUCKETENDDATEMISSING)
			OUTLOG("# Bucket has no end date.");
		else if (type == NOBUCKET)
			OUTLOG("# Has no bucket.");
		else if (type == BUNDLEENDDATEMISSING)
			OUTLOG("# Bundle has no end date.");
		else if (type == UNKNOWNISSUE)
			OUTLOG("# Unsolved issue.");

		OUTLOG("# This issue may not trigger any action, check XML.");
	}

	private static int getFix(BundleInfo _bf, Integer issue) {

		// browse XML and get actions

		int action = 0;

		String _saction = new String();

		DEBLOG("getFix(BundleInfo _bf, Integer issue) " + _bf.getBundleId()
				+ " - " + printIssue(issue));

		ArrayList<String> array = null;

		for (Bundle _b : bundlesDef.getBundle()) {
			if (_b.getName().compareTo(_bf.getBundleId()) == 0) {
				if (_b.getRules() != null) {
					for (Case _c : _b.getRules().getCase()) {

						if ((issue == BUCKETSTARTDATEMISSING && _c.getType()
								.compareTo("bucketStartDateMissing") == 0)
								|| (issue == BUCKETENDDATEMISSING && _c
										.getType().compareTo(
												"bucketEndDateMissing") == 0)
								|| (issue == NOBUCKET && _c.getType()
										.compareTo("bucketMissing") == 0)
								|| (issue == NOCOUNTER && _c.getType()
										.compareTo("counterMissing") == 0)
								|| (issue == BUNDLEENDDATEMISSING && _c
										.getType().compareTo(
												"bundleEndDateMissing") == 0)) {
							for (Action _a : _c.getAction()) {
								if (_a.getType().compareTo("warning") == 0) {
									action = WARNING + action;
									_saction = _saction + printFix(WARNING);
								}
								if (_a.getType().compareTo("delete") == 0) {
									action = DELETE + action;
									_saction = _saction + printFix(DELETE);
								}
								if (_a.getType().compareTo("provision") == 0) {
									action = PROVISION + action;
									_saction = _saction + printFix(PROVISION);
								}
							}
						}

					}
				}
			}
		}
		DEBLOG("Action is getFix(BundleInfo _bf, Integer issue) "
				+ _bf.getBundleId() + " - " + issue + " -> "
				+ (_saction.length() > 0 ? _saction : "NONE"));
		return action;
	}

	private static int getIssue(BundleInfo _bf,
			Collection<BundleInfo> counterColl) {

		int issue = 0;

		String _sissue = new String();

		// no counter at all for this bundle
		if (counterColl == null || counterColl.size() == 0) {
			DEBLOG("getIssue " + printIssue(NOCOUNTER));
			return NOCOUNTER;
		}

		if (counterColl.size() > 1) {
			OMLOG("# Warning: the bundle " + _bf.getBundleId() + " has more counters associated with it.");
			return UNKNOWNISSUE;
		}
		// bundle start date not implemented
		if (_bf.getEndDate() == null || _bf.getEndDate().length() == 0) {
			issue = issue + BUNDLEENDDATEMISSING;
			_sissue = _sissue + printIssue(BUNDLEENDDATEMISSING);
		}
		for (BundleInfo _binf : counterColl) {
			if (_binf.getStartDate() == null
					|| _binf.getStartDate().length() == 0) {
				issue = issue + BUCKETSTARTDATEMISSING;
				_sissue = _sissue + printIssue(BUCKETSTARTDATEMISSING);
			}
			if (_binf.getEndDate() == null || _binf.getEndDate().length() == 0) {
				issue = issue + BUCKETENDDATEMISSING;
				_sissue = _sissue + printIssue(BUCKETENDDATEMISSING);
			}
			if (_binf.getBucket() == null || _binf.getBucket().length() == 0) {
				issue = issue + NOBUCKET;
				_sissue = _sissue + printIssue(NOBUCKET);
			}
			if (_binf.getBucket() != null
					&& _binf.getBucket().compareTo("0") == 0) {
				issue = issue + BUCKETISEXHAUSTED;
				_sissue = _sissue + printIssue(BUCKETISEXHAUSTED);
			}

		}
		DEBLOG("getIssue " + (_sissue.length() > 0 ? _sissue : "NONE")
				+ " val " + issue);
		return issue == 0 ? CTOK : issue;
	}

	private static ArrayList<String> getCounterName(String bundleId) {

		DEBLOG("getCounterName(String bundleId) " + bundleId);

		ArrayList<String> array = null;

		for (Bundle _b : bundlesDef.getBundle()) {
			if (_b.getName().compareTo(bundleId) == 0) {
				array = new ArrayList<String>();
				for (Counter _cs : _b.getCounter()) {
					array.add(_cs.getId());
				}
				return array;
			}
		}

		if (array == null) {
			OMLOG("!!!! Warning getCounterName(String bundleId) " + bundleId
					+ " not configured in XML");
		}

		return array;

	}

	private static Multimap<String, BundleInfo> fetchCounters(
			ArrayList<String> mSISDNS, String FileName) {

		Multimap<String, BundleInfo> fpmap = ArrayListMultimap.create();

		if (sourceData == 0) {
			// file
			BufferedReader br = null;
			try {
				String sCurrentLine;
				br = new BufferedReader(new FileReader(FileName));
				while ((sCurrentLine = br.readLine()) != null) {
					Tuple<String, ArrayList<BundleInfo>> ctList = parseCTRTDB(sCurrentLine, COUNTERS);
					if ( ctList != null){
						for ( BundleInfo _ct: ctList.y){
							fpmap.put(ctList.x + ":" + _ct.getBundleId(), _ct);
						}
					}
				}

			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				try {
					if (br != null)
						br.close();
				} catch (IOException ex) {
					ex.printStackTrace();
				}
			}
		}
		else{
			for (String msisdn : mSISDNS) {

				DEBLOG("+++++++++++++++++++++++++++++");

				ArrayList<BundleInfo> binf = getLdap(msisdn, COUNTERS);

				for (BundleInfo bif : binf) {
					// DEBLOG("fpmap.put(msisdn + \":\" + bif.getBundleId(), bif); "+
					// bif);
					fpmap.put(msisdn + ":" + bif.getBundleId(), bif);
				}
			}

		}
		return fpmap;
	}

	private static Map<String, ArrayList<BundleInfo>> fetchBundles(
			ArrayList<String> MSISDNS, String FileName) {

		
		Map<String, ArrayList<BundleInfo>> fpmap = new HashMap<String, ArrayList<BundleInfo>>();

		if (sourceData == 0) {
			// file
			BufferedReader br = null;
			try {
				String sCurrentLine;
				br = new BufferedReader(new FileReader(FileName));
				while ((sCurrentLine = br.readLine()) != null) {
					Tuple<String, ArrayList<BundleInfo> > _couple = parseCTRTDB(sCurrentLine, BUNDLES);
					if ( _couple != null){
						if (fpmap.containsKey(_couple.x)){
							//add bundles

							fpmap.get(_couple.x).addAll(_couple.y);
						}else{
							fpmap.put(_couple.x, _couple.y);
						}
					}
				}

			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				try {
					if (br != null)
						br.close();
				} catch (IOException ex) {
					ex.printStackTrace();
				}
			}

			
		} else {

			for (String msisdn : MSISDNS) {

				ArrayList<BundleInfo> binf = getLdap(msisdn, BUNDLES);

				fpmap.put(msisdn, binf);
			}
		}
		return fpmap;

	}

	private static Tuple<String, ArrayList<BundleInfo>> parseCTRTDB(
			String sCurrentLine, int Type) {
		
		DEBLOG("CTRTDB [" + sCurrentLine + "]");

		Tuple<String, ArrayList<BundleInfo>> _t = null;
		
		ArrayList <BundleInfo> _bf = new ArrayList <BundleInfo>();
		
		if (rawFile){
			/*
			 * 'I' '447899418018:0:0:ALL:1' 'MDN' '0' '0' '0' '' '' 1391227450 0 0 '' '' 
			 * 'D01' '0' '0' '0' '20140201' '' 1391227450 0 0 '' '' 
			 * 'D02' '0' '0' '0' '20140201' '' 1391227450 0 0 '' '' 
			 * 'D03' '0' '0' '0' '20140201' '' 1391227450 0 0 '' '' 
			 * '' '0' '0' '0' '' '' 0 0 0 '' '' '' '0' '0' '0' '' '' 0 0 0 '' '' 0 0 0 0 0 0 '' '' '' '' '' '' '' '' '' '' 0 0 0 0 '' '' '' '' '' '00' '00' '00' '00' '00' '00' '0' '0' '0' '0' '0' '0' '0' '0' '0' '0' '0' '0' '' '' '' '' '' '' '0' '0' '0' '0' '0' '0' 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 'N' 'N' 'N' 'N' 'N' 'N' 'N' 'N' 'N' 'N' 'N' 'N' 'N' 'N' 'N' 'N' 'N' 'N' 'N' 'N' 'N' 'N' 'N' 'N' 'N' 'N' 'N' 'N' 'N' 'N' 'N' 'N' 'N' 'N' 'N' 'N' 'N' 'N' 'N' 'N' 'N' 'N' 'N' 'N' 'N' |

			 */
			String[] parsed = sCurrentLine.split(" ");
			String[] INDEX = parsed[1].replaceAll("\'","").split(":");			
			if ( INDEX[2].compareTo(""+Type) != 0)
				return null;
			else{
				BundleInfo _bi = null;
				for (int i = 0 ; i < 6 ; i ++){
					if (parsed[13 + (i * 11)].replace("\'", "").length()>0){
						_bi = new BundleInfo();
						_bi.setBundleId(parsed[13 + (i * 11)].replace("\'", ""));
						_bi.setStartDate(parsed[17 + (i * 11)].replace("\'", ""));
						_bi.setEndDate(parsed[18 + (i * 11)].replace("\'", ""));
						_bi.setBucket(parsed[15 + (i * 11)].replace("\'", ""));
						_bf.add(_bi);
						DEBLOG("Line " + sCurrentLine);
						DEBLOG("_bi.setBundleId(parsed[13 + (i * 11)].replace(\"\'\", \"\")); " + parsed[13 + (i * 11)].replace("\'", ""));
						DEBLOG("_bi.setStartDate(parsed[17 + (i * 11)].replace(\"\'\", \"\")); " + parsed[17 + (i * 11)].replace("\'", ""));
						DEBLOG("_bi.setEndDate(parsed[19 + (i * 11)].replace(\"\'\", \"\")); " + parsed[19 + (i * 11)].replace("\'", ""));
						DEBLOG("_bi.setBucket(parsed[15 + (i * 11)].replace(\"\'\", \"\")); " + parsed[15 + (i * 11)].replace("\'", ""));
					}
				}
				_t = new Tuple<String, ArrayList<BundleInfo>>(INDEX[0], _bf);
			}
		}else{
			String[] parsed = sCurrentLine.split(",");
			String[] INDEX = parsed[0].split(":");
			if ( INDEX[2].compareTo(""+Type) != 0)
				return null;
			else{
				BundleInfo _bi = null;
				for (int i = 0 ; i < 6 ; i ++){
					//CT1		.		BUCK		.		START			END		STARTT			ENDT		.		.		.
					//'D01'		'1'		'0'			'0'		'20140111'		''		1389462542		0			0		''		''
					// 'I' '447818455168:0:0:ALL:1' 'MDN' '1' '0' '0' '20140118' '' 1389617065 0 0 '' '' 
					if (parsed[2 + (i * 11)].replace("\'", "").length()>0){
						_bi = new BundleInfo();
						_bi.setBundleId(parsed[1 + (i * 11)]);
						_bi.setStartDate(parsed[5 + (i * 11)]);
						_bi.setEndDate(parsed[6 + (i * 11)]);
						_bi.setBucket(parsed[3 + (i * 11)]);
						_bf.add(_bi);
					}
				}
				_t = new Tuple<String, ArrayList<BundleInfo>>(INDEX[0], _bf);
			}
		}
		

		return _t;
	}
	
	private static ArrayList<BundleInfo> getLdap(String msisdn, int type) {

		// get all tuples from two ldap searches
		ArrayList<BundleInfo> bundleInfos = null;

		if (test) {
			if (type == BUNDLES)
				return fillTestB();
			if (type == COUNTERS)
				return fillTestC();
		}
		try {

			bundleInfos = new ArrayList<BundleInfo>();

			for (int PAGE = 1; PAGE <= 2; PAGE++) {

				String s = null;

				String ldapExec = "ldapsearch -b dview=XAN-IN-RDR3_request_data -h 127.0.0.1 -u -V 2 -l 1000 -w123 -p 1972 -s one -D dview=XAN-IN-RDR3_request_data sid=OP=Q;TBL_NAME=CTRTDB;TBL_KEY="
						+ msisdn + ":0:" + type + ":ALL:" + PAGE + ";";
				DEBLOG("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
				DEBLOG(ldapExec);
				DEBLOG("-------------------------------------------------------------------");

				Process p = Runtime.getRuntime().exec(ldapExec);

				p.waitFor();

				BufferedReader stdInput = new BufferedReader(
						new InputStreamReader(p.getInputStream()));

				BufferedReader stdError = new BufferedReader(
						new InputStreamReader(p.getErrorStream()));

				// read the output from the command
				boolean loadit = false;
				String bigResult = new String();
				DEBLOG("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
				while ((s = stdInput.readLine()) != null) {
					DEBLOG("[" + s + "]");
					if (s.startsWith("rd") || loadit) {
						loadit = true;
						bigResult = bigResult + s;
					}
				}
				if (bigResult.length() < 4) {
					DEBLOG("Empty rd " + msisdn);
					DEBLOG(bigResult);
					break;
				}
				DEBLOG(bigResult.substring(4).replaceAll(" ", ""));
				DEBLOG("-------------------------------------------------------------------");

				String formattedResult = bigResult.substring(4).replaceAll(" ",
						"");

				String tuples[] = formattedResult.split(";");

				for (int i = 1; i <= 6; i++) {

					String cid = new String();
					String sdt = new String();
					String edt = new String();
					String cva = new String();

					for (String t : tuples) {
						if (t.startsWith("CID" + i)) {
							cid = t.substring(5);
							continue;
						}
					}
					for (String t : tuples) {
						if (t.startsWith("SD" + i)) {
							sdt = t.substring(4);
							continue;
						}
					}
					for (String t : tuples) {
						if (t.startsWith("ED" + i)) {
							edt = t.substring(4);
							continue;
						}
					}
					for (String t : tuples) {
						if (t.startsWith("CV" + i)) {
							cva = t.substring(4);
							continue;
						}
					}

					if (cid.compareTo("") != 0) {
						BundleInfo _bf = new BundleInfo();
						_bf.setBucket(cva);
						_bf.setBundleId(cid);
						_bf.setStartDate(sdt);
						_bf.setEndDate(edt);
						bundleInfos.add(_bf);
					}
				}
			}
		} catch (Exception e) {
			OMLOG("exception happened - here's what I know: ");
			e.printStackTrace();
			System.exit(-1);
		}
		return bundleInfos;
	}

	// private static Map<String, String[]> fetchFromCTDB(Integer TYPE,
	// String[] MSISDNS) {
	//
	// Map<String, String[]> fpmap = new HashMap<String, String[]>();
	//
	// for (String msisdn : MSISDNS) {
	//
	// OMLOG("+++++++++++++++++++++++++++++");
	// OMLOG("[" + msisdn + "] " + (TYPE == 0 ? "BUNDLES" : "COUNTERS"));
	//
	// // boolean hasMorePages = true;
	// for (int PAGE = 1; PAGE <= 2; PAGE++)
	// // while (hasMorePages) {
	// try {
	//
	// String s = null;
	//
	// Process p = Runtime
	// .getRuntime()
	// .exec("ldapsearch -b dview=XAN-IN-RDR3_request_data -h 127.0.0.1 -u -V 2 -l 1000 -w123 -p 1972 -s one -D dview=XAN-IN-RDR3_request_data sid=OP=Q;TBL_NAME=CTRTDB;TBL_KEY="
	// + msisdn
	// + ":0:"
	// + TYPE
	// + ":ALL:"
	// + PAGE
	// + ";");
	//
	// p.waitFor();
	//
	// BufferedReader stdInput = new BufferedReader(
	// new InputStreamReader(p.getInputStream()));
	//
	// BufferedReader stdError = new BufferedReader(
	// new InputStreamReader(p.getErrorStream()));
	//
	// // read any errors from the attempted command
	// OMLOG("Here is the standard error of the command (if any):\n");
	// while ((s = stdError.readLine()) != null) {
	// // hasMorePages = false;
	// System.out.println(s);
	// }
	//
	// // read the output from the command
	// boolean loadit = false;
	// String bigResult = new String();
	// while ((s = stdInput.readLine()) != null) {
	// DEBLOG("[" + s + "]");
	// if (s.startsWith("rd") || loadit) {
	// loadit = true;
	// bigResult = bigResult + s;
	// }
	// }
	// if (bigResult.length() < 4) {
	// OMLOG("Empty rd " + msisdn);
	// DEBLOG(bigResult);
	// continue;
	// }
	// DEBLOG(bigResult.substring(4).replaceAll(" ", ""));
	// String formattedResult = bigResult.substring(4).replaceAll(
	// " ", "");
	// String tuples[] = formattedResult.split(";");
	//
	// for (String t : tuples) {
	// DEBLOG(t);
	//
	// }
	//
	// // -----------------------------------------
	// // MSISDN:FPID:PAGE:POSITION
	// String cid = new String("");
	// String endd = new String("");
	// String startd = new String("");
	// String cvv = new String("");
	//
	// // replace with method
	// for (int i = 1; i <= 6; i++) {
	// String dates[] = new String[4];
	// dates[0] = "";
	// dates[1] = "";
	// dates[2] = "";
	// dates[3] = "";
	// for (String t : tuples) {
	// if (t.startsWith("CID" + i)) {
	// cid = t.substring(5);
	// continue;
	// }
	// }
	// for (String t : tuples) {
	// if (t.startsWith("SD" + i)) {
	// startd = t.substring(4);
	// continue;
	// }
	// }
	// for (String t : tuples) {
	// if (t.startsWith("ED" + i)) {
	// endd = t.substring(4);
	// continue;
	// }
	// }
	// for (String t : tuples) {
	// if (t.startsWith("CV" + i)) {
	// cvv = t.substring(4);
	// continue;
	// }
	// }
	//
	// String keit = new String();
	// keit = msisdn + ":" + PAGE + ":" + i;
	// dates[0] = cid;
	// dates[1] = startd;
	// dates[2] = endd;
	// dates[3] = cvv;
	// fpmap.put(keit, dates);
	// OMLOG("put [" + keit + "][" + dates[0] + "]["
	// + dates[1] + "][" + dates[2] + "][" + dates[3]
	// + "]");
	//
	// }
	//
	// // read any errors from the attempted command
	// OMLOG("Here is the standard error of the command (if any):\n");
	// while ((s = stdError.readLine()) != null) {
	// // hasMorePages = false;
	// System.out.println(s);
	// }
	//
	// } catch (Exception e) {
	// OMLOG("exception happened - here's what I know: ");
	// e.printStackTrace();
	// System.exit(-1);
	// }
	// OMLOG("-----------------------------");
	// }
	// // }
	// return fpmap;
	// }

	private static ArrayList<BundleInfo> fillTestB() {

		// BundleInfo[] bf = new BundleInfo[5];
		//
		// ArrayList<BundleInfo> bf = new ArrayList<BundleInfo>;
		//
		// bf[0] = new BundleInfo();
		// bf[1] = new BundleInfo();
		// bf[2] = new BundleInfo();
		// bf[3] = new BundleInfo();
		// bf[4] = new BundleInfo();
		// // bf[5] = new BundleInfo();
		// // bf[6] = new BundleInfo();
		// // bf[7] = new BundleInfo();
		// // bf[8] = new BundleInfo();
		// // bf[9] = new BundleInfo();
		// // bf[10] = new BundleInfo();
		// // bf[11] = new BundleInfo();
		//
		// bf[0].setBundleId("FP_VF_MDN");
		// bf[0].setStartDate("20140101");
		// bf[1].setBundleId("FP_VF_VMI");
		// bf[1].setStartDate("20140101");
		// bf[2].setBundleId("FP_VF_C06");
		// bf[2].setStartDate("20140101");
		// bf[2].setEndDate("20140228");
		// bf[3].setBundleId("FP_VF_S04");
		// bf[3].setStartDate("20140101");
		// bf[3].setEndDate("20140228");
		// bf[4].setBundleId("FP_VF_D26");
		// bf[4].setStartDate("20140101");
		// bf[4].setEndDate("20140228");
		//
		// return bf;

		return null;
	}

	private static ArrayList<BundleInfo> fillTestC() {

		return null;

		// BundleInfo[] bf = new BundleInfo[7];
		//
		// bf[0] = new BundleInfo();
		// bf[1] = new BundleInfo();
		// bf[2] = new BundleInfo();
		// bf[3] = new BundleInfo();
		// bf[4] = new BundleInfo();
		// bf[5] = new BundleInfo();
		// bf[6] = new BundleInfo();
		//
		// // bf[6] = new BundleInfo();
		// // bf[7] = new BundleInfo();
		// // bf[8] = new BundleInfo();
		// // bf[9] = new BundleInfo();
		// // bf[10] = new BundleInfo();
		// // bf[11] = new BundleInfo();
		//
		// bf[0].setBundleId("C06");
		// bf[0].setStartDate("20140101");
		//
		// bf[1].setBundleId("S04");
		// bf[1].setStartDate("20140101");
		//
		// bf[2].setBundleId("MDN");
		// bf[2].setStartDate("20140101");
		// bf[2].setEndDate("20140228");
		//
		// bf[3].setBundleId("D26");
		// bf[3].setStartDate("20140101");
		// bf[3].setEndDate("20140228");
		//
		// bf[4].setBundleId("D01");
		// bf[4].setStartDate("20140101");
		// bf[4].setEndDate("20140228");
		//
		// bf[5].setBundleId("D02");
		// bf[5].setStartDate("20140101");
		// bf[5].setEndDate("20140228");
		//
		// bf[6].setBundleId("D03");
		// bf[6].setStartDate("20140101");
		// bf[6].setEndDate("20140228");
		//
		// return bf;

	}

	private static void DEBLOG(Object string) {
		if (debuglogLevel == 0) {
			return;
		} else if (debuglogLevel == 1) {
			System.out.println(string.toString());
		}
	}

	private static void LINE(int i) {
		if (debuglogLevel == 0) {
			return;
		} else if (debuglogLevel == 1) {
			System.out.println("LINE " + i);

		}
	}

	private static void OMLOG(Object string) {
		if (omlogLevel == 0) {
			return;
		} else if (omlogLevel == 1) {
			System.out.println(string.toString());
		}
	}
	
	private static void STATLOG(Object string) {
		if (!statsOnly) {
			return;
		} else {
			System.out.println(string.toString());
		}
	}


	private static void OMLOGd(Object string) {
		if (omlogLevel == 0) {
			return;
		} else if (omlogLevel == 1 ) {
			System.out.print(string.toString());
		}
	}

	private static void OUTLOG(Object string) {
		if (outputLevel == 0 ) {
			return;
		} else if (outputLevel == 1 && !statsOnly) {
			System.out.println(string.toString());
		}
	}

	private static String expandSArray(ArrayList<String> s) {
		String sss = new String();
		if (s == null)
			return "";
		for (String ss : s) {
			sss = sss + "[" + ss + "]";
		}
		return sss;
	}

	// this will be replaced by xml
	String[] getBucketId(String fp) {

		if (fp.compareTo("FP_VF_VMI") == 0) {
			String[] counters = new String[3];
			counters[0] = "D01";
			counters[1] = "D02";
			counters[2] = "D03";
			return counters;
		} else {
			String[] counters = new String[1];
			counters[0] = fp.substring(6);
			return counters;
		}

	}

	private static void printMap2(Map<String, Integer> _totQbun) {

		Iterator iterator = _totQbun.entrySet().iterator();
		while (iterator.hasNext()) {
			Map.Entry mapEntry = (Map.Entry) iterator.next();
			String theK = (String) mapEntry.getKey();
			DEBLOG("The key is: " + theK + " the value is :"
					+ mapEntry.getValue());
		}

	}

	private static void printArray(ArrayList<BundleInfo> _binfo) {
		// TODO Auto-generated method stub
		for (BundleInfo __bf : _binfo) {
			DEBLOG("ArrayList " + __bf.getBundleId() + " is queued "
					+ __bf.isQueued() + " place " + __bf.getPlaceInQueue());
		}
	}

	private static void printMMap(Multimap<String, BundleInfo> counters2) {

		Iterator iterator = counters2.entries().iterator();
		while (iterator.hasNext()) {
			Map.Entry mapEntry = (Map.Entry) iterator.next();
			String theK = (String) mapEntry.getKey();
			DEBLOG("The key is: " + theK + ",value is :"
					+ ((BundleInfo) mapEntry.getValue()).getBundleId());
		}
	}

	private static void printMap(Map<String, ArrayList<BundleInfo>> bundles2) {

		Iterator iterator = bundles2.entrySet().iterator();
		while (iterator.hasNext()) {
			Map.Entry mapEntry = (Map.Entry) iterator.next();
			String theK = (String) mapEntry.getKey();
			DEBLOG("The key is: " + theK);
			for (BundleInfo _bf : (ArrayList<BundleInfo>) mapEntry.getValue())
				DEBLOG("        the value is :" + _bf.getBundleId());
		}

	}

	private static String printIssue(int issue) {
		if (issue == CTOK)
			return "CTOK";
		else if (issue == BUCKETSTARTDATEMISSING)
			return "STARTDATEMISSING";
		else if (issue == BUCKETENDDATEMISSING)
			return "ENDDATEMISSING";
		else if (issue == NOBUCKET)
			return "NOBUCKET";
		else if (issue == NOCOUNTER)
			return "NOCOUNTER";
		else if (issue == BUNDLEENDDATEMISSING)
			return "BUNDLEENDDATEMISSING";
		else if (issue == BUCKETISEXHAUSTED)
			return "BUCKETISEXHAUSTED";

		return null;
	}

	private static String printFix(int fix) {
		if (fix == SKIP)
			return "SKIP";
		else if (fix == WARNING)
			return "WARNING";
		else if (fix == DELETE)
			return "DELETE";
		else if (fix == PROVISION)
			return "PROVISION";
		return null;
	}

}

// Map<String, String[]> bundles = new HashMap<String, String[]>();
// Iterator iterator = counters.entrySet().iterator();
// while (iterator.hasNext()) {
// Map.Entry mapEntry = (Map.Entry) iterator.next();
// countersSummary.put(arg0, arg1)
// System.out.println("The key is: " + mapEntry.getKey()
// + ",value is :" + mapEntry.getValue());
// }
// for (String s : MSISDNS) {
// for (int PAGE = 1; PAGE <= 2; PAGE++)
// for (int i = 1; i <= 6; i++) {
// OUTLOG("+++++++++++++++++++++++++++++++++++++++++");
// OUTLOG(s + ":"+PAGE+":" + i + " "
// + expandSArray(bundles.get(s + ":"+PAGE+":" + i)));
// OUTLOG(s + ":"+PAGE+":" + i + " "
// + expandSArray(counters.get(s + ":"+PAGE+":" + i)));
// OUTLOG("-----------------------------------------");
//
// }
// }

// //Start analysis
// for (String s : MSISDNS)
// for (int page = 1 ; page <= 2 ; page ++)
// for (int counter = 1 ; counter <= 6 ; counter ++){
//
// }

